
package DAO;

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.*;
import DTO.*;
import Exception.*;

/**
 * This class represents proxy class for data access from database and
 * controls the data access centrally.This class delegates the responsibility
 * of data access to various other classes.
 * @author Tony
 */
public class DAO {

    private Connection conn;
    private AdminDAO adminDAO;
    private AddressDAO addressDAO;
    private ClerkDAO clerkDAO;
    private CustomerDAO customerDAO;
    private ItemDAO itemDAO;
    private OrderDAO orderDAO;
    private PaymentDAO paymentDAO;
    private PromoDAO promoDAO;
    private ShippingDAO shipDAO;
    private StoreDAO storeDAO;
    private CategoryDAO categoryDAO;
    private static final Logger log = Logger.getLogger(DAO.class.getName());

    /**
     * This is default constructor and it retrieves a connection object, then
     * sets other DAO objects/proxies for
     * {@link AddressDAO}{@link AdminDAO}{@link ClerkDAO}{@link CustomerDAO}
     * {@link ItemDAO}{@link OrderDAO}{@link PaymentDAO}{@link PromoDAO}
     * {@link ShippingDAO}{@link StoreDAO}{@link ShippingDAO}{@link CategoryDAO}
     * @throws KwickKioskDBException
     * @link KwickKioskDBException}
     */
    public DAO() throws KwickKioskDBException {
        ConnectionDAO connectionDAO = new ConnectionDAO();
        conn = connectionDAO.getConn();

        addressDAO = new AddressDAO(conn);
        adminDAO = new AdminDAO(conn);
        clerkDAO = new ClerkDAO(conn);
        customerDAO = new CustomerDAO(conn);
        itemDAO = new ItemDAO(conn);
        orderDAO = new OrderDAO(conn);
        paymentDAO = new PaymentDAO(conn);
        promoDAO = new PromoDAO(conn);
        shipDAO = new ShippingDAO(conn);
        storeDAO = new StoreDAO(conn);
        shipDAO = new ShippingDAO(conn);

        categoryDAO = new CategoryDAO(conn);

    }

    /**
     * This is constructor with userName, password, URL and it retrieves a
     * connection object, then sets other DAO objects/proxies for
     * {@link AddressDAO}{@link AdminDAO}{@link ClerkDAO}{@link CustomerDAO}
     * {@link ItemDAO}{@link OrderDAO}{@link PaymentDAO}{@link PromoDAO}
     * {@link ShippingDAO}{@link StoreDAO}{@link ShippingDAO}{@link CategoryDAO}
     * @param userName
     * @param password
     * @param url
     * @throws KwickKioskDBException
     * @link KwickKioskDBException}
     */
    public DAO(String userName, String password, String url) throws KwickKioskDBException {
        ConnectionDAO connectionDAO = new ConnectionDAO( userName,  password,  url);
        conn = connectionDAO.getConn();

        addressDAO = new AddressDAO(conn);
        adminDAO = new AdminDAO(conn);
        clerkDAO = new ClerkDAO(conn);
        customerDAO = new CustomerDAO(conn);
        itemDAO = new ItemDAO(conn);
        orderDAO = new OrderDAO(conn);
        paymentDAO = new PaymentDAO(conn);
        promoDAO = new PromoDAO(conn);
        shipDAO = new ShippingDAO(conn);
        storeDAO = new StoreDAO(conn);
        shipDAO = new ShippingDAO(conn);

        categoryDAO = new CategoryDAO(conn);

    }

    /**
     * This method closes the connection objects and disconnects
     * application from database.
     * @throws {@link KwickKioskDBException}
     */
    public void disconnectDB() throws KwickKioskDBException {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException ex) {
                log.log(Level.SEVERE, null, ex);
                throw new KwickKioskDBException("DAO : disconnectDB",
                        ex.getMessage());
            }
        }
    }

    /**
     * This method retrieves administrator information from database
     * using adminDAO proxy. {@link AdminDAO}
     * @param id an integer
     * @return AdminDTO object
     * @throws {@link KwickKioskDBException}
     */
    public Admin getAdminInfo(int id) throws KwickKioskDBException {
        return adminDAO.getAdmin(id);
    }

    /**
     * This method retrieves all the categories of products from
     * database using categoryDAO proxy. {@link CategoryDAO}
     * @return a list of categories
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Category> getCategories() throws KwickKioskDBException {
        return categoryDAO.getCategories();
    }

    //////////////////////////////////////////////////////////////////////
    // Clerk
    /**
     * This method inserts clerk information into database
     * uses clerkDAO as a proxy. {@link ClerkDAO}
     * @param passCode  a string representing clerk password
     * @param firstName a string representing clerk first name
     * @param lastName  a string representing clerk last name
     * @return an integer representing clerk id.
     * @throws {@link KwickKioskDBException}
     */
    public int addClerk(String passCode, String firstName,
            String lastName) throws KwickKioskDBException {
        return clerkDAO.registerClerk(passCode, firstName, lastName);
    }

    /**
     * This method updates clerk information into database. uses {@link ClerkDAO} proxy
     * @param c clerk DTO object encapsulating clerk information
     * @return a boolean flag 
     * @throws {@link KwickKioskDBException}
     */
    public boolean updateClerk(Clerk c) throws KwickKioskDBException {
        return clerkDAO.updateClerk(c);
    }

    /**
     * This method deletes a clerk tuple from database using {@link ClerkDAO} proxy
     * @param ckid an integer representing clerk id.
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean deleteClerk(int ckid) throws KwickKioskDBException {
        return clerkDAO.removeClerk(ckid);
    }

    /**
     * This method retrieves clerk information from database {@link ClerkDAO} proxy
     * @param ckid an integer
     * @return ClerkDTO object encapsulating clerk information
     * @throws {@link KwickKioskDBException}
     */
    public Clerk getClerkInfo(int ckid) throws KwickKioskDBException {
        return clerkDAO.searchByID(ckid);
    }

    /**
     * This method retrieves clerk information from database by a first name criteria
     * using {@link ClerkDAO} proxy
     * @param name a string
     * @return an array list object
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Clerk> getClerksByFirstName(String name)
            throws KwickKioskDBException {
        return clerkDAO.searchByFirstName(name);
    }

    /**
     * This method retrieves clerk information by last name criteria
     * using  {@link ClerkDAO} proxy
     * @param name string
     * @return an array list object
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Clerk> getClerksByLastName(String name)
            throws KwickKioskDBException {
        return clerkDAO.searchByLastName(name);
    }

    /**
     * This method retrieves information of all clerks in database using {@link ClerkDAO} proxy
     * @return an array list object
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Clerk> getAllClerks() throws KwickKioskDBException {
        return clerkDAO.getAllClerks();
    }

    //////////////////////////////////////////////////////////////////
    // Customer

    /**
     * This method inserts customer information into database using {@link CustomerDAO}
     * @param passCode  a string represents encrypted customer password
     * @param firstName a string represents customer first name
     * @param lastName a string represents customer last name
     * @param email a string represents customer email
     * @param phoneNumber a string represents customer phone number
     * @return an integer customer id
     * @throws {@link KwickKioskDBException}
     */
    public int addCustomer(String passCode, String firstName,
            String lastName, String email, String phoneNumber)
            throws KwickKioskDBException {
        return customerDAO.registerCustomer(passCode,
                firstName,
                lastName,
                email,
                phoneNumber);
    }

    /**
     * This method retrieves customer information from database  using {@link CustomerDAO}
     * @param csid an integer customer id.
     * @return a Customer data transfer object encapsulating customer information
     * @throws {@link KwickKioskDBException}
     * @throws {@link EmptySet}
     */
    public Customer getCustomer(int csid) throws KwickKioskDBException, EmptySet {
        return customerDAO.searchByID(csid);
    }

    /**
     * This method updates customer information in database using {@link CustomerDAO}
     * @param c customer data transfer object
     * @return a boolean flag indicates success/failure of transaction
     * @throws {@link KwickKioskDBException}
     */
    public boolean updateCustomerInfo(Customer c) throws KwickKioskDBException {
        return customerDAO.updateCustomer(c);
    }

    /**
     * This method checks if email provided by customer is already present in database
     * using {@link CustomerDAO} proxy
     * @param email a string
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean isEmailInDB(String email) throws KwickKioskDBException {
        return customerDAO.unqiueEmail(email);
    }

    /**
     * This method checks if phone provided by customer is already present in database
     * using {@link CustomerDAO} proxy.
     * @param phone a string
     * @return a boolean
     * @throws {@link KwickKioskDBException}
     */
    public boolean isPhoneInDB(String phone) throws KwickKioskDBException {
        return customerDAO.unqiuePhone(phone);
    }

    /**
     * This method retrieves all addresses associated with a customer using {@link CustomerDAO} proxy.
     * @param csid an integer
     * @return array list of Address data transfer objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Address> getCustomerAddress(int csid)
            throws KwickKioskDBException {

        return customerDAO.getAddressList(csid);
    }

    /**
     * This method retrieves shipping method associated with a province using {@link ShippingDAO} proxy
     * @param province a string
     * @return a list of Shipping Method data transfer objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<ShippingMethod> getShipMethods(String province)
            throws KwickKioskDBException {

        return shipDAO.getShippingMethodList(province);
    }

    /**
     * This method inserts an address information into database using {@link AddressDAO} proxy
     * @param csid an integer representing customer id
     * @param aptNo a string representing apartment number
     * @param stNo an integer representing street number
     * @param streetName a string representing street name
     * @param postCode a string representing postal code
     * @param city a string representing city
     * @param province a string representing province
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean addAddressToCustomer(int csid,
            String aptNo, int stNo,
            String streetName,
            String postCode,
            String city, String province) throws KwickKioskDBException {
        int aid = addressDAO.addNewAddress(aptNo, stNo, streetName,
                postCode, city, province);

        if (aid != -1) {
            return customerDAO.addAddressToCustomer(csid, aid);
        }

        return false;
    }

   /**
    * This method updates customer address information into database using {@link AddressDAO} proxy
    * @param address  data transfer object encapsulating address information
    * @return boolean flag
    * @throws {@link KwickKioskDBException}
    */
    public boolean updateAddress(Address address) throws KwickKioskDBException {
        return addressDAO.updateAddress(address);
    }

    /**
     * This method removes an address associated with customer from database  using {@link CustomerDAO} proxy
     * @param csid an integer representing customer id
     * @param aid an integer representing address id
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean removeAddressToCustomer(int csid, int aid)
            throws KwickKioskDBException {
        return customerDAO.removeAddressToCustomer(csid, aid);
    }

    ///////////////////////////////////////////////////////////////////////
    // Items for Admin

    /**
     * This method adds a new item to inventory using {@link ItemDAO} proxy
     * @param i item data transfer object
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean addItemToInventory(Item i) throws KwickKioskDBException {
        return itemDAO.addItem(i);
    }

    /**
     * This method deletes an item from database using using {@link ItemDAO} proxy
     * @param upc a string representing item  code
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean takeItemOffTheShelf(String upc)
            throws KwickKioskDBException {

        return itemDAO.deleteItem(upc);
    }

    /**
     * This methods updates item information into database using {@link ItemDAO} proxy.
     * @param oldUPC item code in database
     * @param i item data transfer object
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean updateItemInfo(String oldUPC, Item i)
            throws KwickKioskDBException {

        return itemDAO.updateItem(oldUPC, i);
    }

    /**
     * This method searches an item in database by item name as criteria using {@link AdminDAO} proxy
     * @param keywords  string representing search criteria
     * @return array list object of item data transfer objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchItemByName(String keywords)
            throws KwickKioskDBException {
        return adminDAO.searchByName(keywords);
    }

   /**
    * This method searches item in database by item code as search criteria using {@link AdminDAO} proxy.
    * @param upc a string for item code
    * @return item data transfer object
    * @throws {@link KwickKioskDBException}
    */
    public Item searchItemByUPC(String upc) throws KwickKioskDBException {
        return adminDAO.searchByUPC(upc);
    }

    /**
     * This method retrieves item information from database using item manufacturer as criteria.
     * uses {@link AdminDAO} proxy
     * @param make a string representing item manufacturer
     * @return an array list object of item data transfer objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchItemByMake(String make)
            throws KwickKioskDBException {
        return adminDAO.searchByMake(make);
    }
    /**
     * This method searches item in database using item model as criteria.
     * uses {@link AdminDAO} proxy
     * @param model a string
     * @return an array list object of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchItemByModel(String model)
            throws KwickKioskDBException {
        return adminDAO.searchByModel(model);
    }

    /**
     * This method searches item in database using a keyword search.
     * uses {@link AdminDAO} proxy
     * @param keywords a string
     * @return an array list object of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchItemByDescription(String keywords)
            throws KwickKioskDBException {
        return adminDAO.searchByDescription(keywords);
    }

    /**
     * This method searches item based on a category id.
     * uses {@link AdminDAO} proxy
     * @param ctid an integer
     * @return array list of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getAdminItemsByCategory(int ctid)
            throws KwickKioskDBException {
        return adminDAO.getItemsByCategory(ctid);
    }

    /**
     * This method searches items in database by a category id and brand.
     * uses {@link AdminDAO} proxy
     * @param ctid an integer category id
     * @param brand a string  brand
     * @return an array list of objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getAdminItemsByCategoryAndBrand(int ctid,
            String brand)
            throws KwickKioskDBException {
        return adminDAO.getItemsByCategoryAndBrand(ctid, brand);
    }

    /**
     * This method searches items based on a price range criteria.
     * uses {@link AdminDAO} proxy
     * @param ctid an integer
     * @param lower a double value for lower limit
     * @param upper a double value for upper limit
     * @return a list of item objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getAdminItemsByPriceRange(int ctid,
            double lower, double upper) throws KwickKioskDBException {
        return adminDAO.getItemsByPriceRange(ctid, lower, upper);
    }

    /**
     * This method retrieves all items in database using {@link AdminDAO} proxy
     * @return an array list of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getAllItems() throws KwickKioskDBException {
        return adminDAO.getAllItems();
    }

    /**
     * This method searches items in store based on store name as search criteria.
     * uses {@link ItemDAO} proxy
     * @param storeName a string
     * @return an array list of item data transfer objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getItemsInStore(String storeName)
            throws KwickKioskDBException {

        return itemDAO.getAllItems(storeName);
    }

    ///////////////////////////////////////////////////////////////////
    // Promotion

    /**
     * This method adds promotion in database using {@link PromoDAO} proxy
     * @param promoName  a string for name of promotion
     * @param startDate  a string representing promotion start date
     * @param endDate    a string representing promotion end date
     * @param promoAmount a double promotion amount for this promotion
     * @param storeCardReq integer indicating whether promotion has pre requirement of store card or not.
     * @return a boolean flag 
     * @throws {@link KwickKioskDBException}
     */
    public boolean openPromotion(String promoName,
            String startDate,
            String endDate,
            double promoAmount,
            int storeCardReq) throws KwickKioskDBException {
        return promoDAO.addPromo(promoName, startDate, endDate,
                promoAmount, storeCardReq);
    }

    /**
     * This method updates promotion information in database using {@link PromoDAO} proxy.
     * @param p promotion data transfer object encapsulating promotion information
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean updatePromotion(Promotion p) throws KwickKioskDBException {
        return promoDAO.updatePromo(p);
    }

    /**
     * This method removes a promotion from database using {@link PromoDAO} proxy
     * @param prid an integer for promotion id in database
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean removePromotion(int prid) throws KwickKioskDBException {
        return promoDAO.removePromotion(prid);
    }

    /**
     * This method retrieves all promotions associated with an item using {@link PromoDAO} proxy.
     * @param upc a string representing item code in database
     * @return a list of promotions 
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Promotion> getPromotionList(String upc)
            throws KwickKioskDBException {
        return promoDAO.getPromotionList(upc);
    }

    /**
     * This method returns all items associated with a promotion using {@link PromoDAO} proxy.
     * @param prid an integer representing promotion id
     * @return list of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getItemByPromo(int prid)
            throws KwickKioskDBException {
        return promoDAO.getItemByPromo(prid);
    }

    /**
     * This method retrieves all promotions from database using {@link PromoDAO} proxy.
     * @return a list of promotions
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Promotion> getAllPromotions()
            throws KwickKioskDBException {

        return promoDAO.getAllPromotions();
    }

    /**
     * This method associates a new item with a promotion using {@link ItemDAO} proxy.
     * @param upc  a string for item code
     * @param prid an integer for promotion code
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean addItemToPromotion(String upc, int prid)
            throws KwickKioskDBException {

        return itemDAO.addItemToPromotion(upc, prid);
    }

    /**
     * This method removes an item from promotion using {@link PromoDAO} proxy.
     * @param upc a string for item code
     * @param prid an integer for promotion code
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean removeItemFromPromotion(String upc, int prid)
            throws KwickKioskDBException {
        return promoDAO.removeItemFromPromotion(upc, prid);
    }

    /**
     * This method checks if any promotion is associated with an item using {@link PromoDAO} proxy.
     * @param upc a string for item code
     * @param prid an integer for promotion code
     * @return boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean isItemInPromotion(String upc, int prid)
            throws KwickKioskDBException {
        return promoDAO.isItemInPromotion(upc, prid);
    }

    /**
     * This method searches a promotion from database using {@link PromoDAO} proxy.
     * @param id an integer for promotion code as search criteria
     * @return a promotion data transfer object
     * @throws {@link KwickKioskDBException}
     */
    public Promotion searchByID(int id) throws KwickKioskDBException {
        return promoDAO.searchByID(id);
    }

    /**
     * This method searches a promotion using  promotion name as search criteria.
     * uses {@link PromoDAO} proxy.
     * @param keywords a string for keyword
     * @return a list of promotions
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Promotion> searchPromoByName(String keywords)
            throws KwickKioskDBException {

        return promoDAO.searchByName(keywords);
    }

    /**
     * This method searches a promotion by start date as input using {@link PromoDAO} proxy.
     * @param startDate a string for promotion start date
     * @return a list of promotions.
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Promotion> searchByStartDate(String startDate)
            throws KwickKioskDBException {

        return promoDAO.searchByStartDate(startDate);
    }

    /**
     * This method searches a promotion by end date as input using {@link PromoDAO} proxy.
     * @param endDate a string for promotion end date
     * @return a list of promotions.
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Promotion> searchByEndDate(String endDate)
            throws KwickKioskDBException {

        return promoDAO.searchByEndDate(endDate);
    }

    ////////////////////////////////////////////////////////////////////////
    // Items in store

    /**
     * This method searches an item in a particular store using {@link ItemDAO} proxy.
     * @param upc  a string for item code.
     * @param storeName a string for store name.
     * @return an item object
     * @throws {@link KwickKioskDBException}
     */
    public Item searchByUPC(String upc, String storeName)
            throws KwickKioskDBException {

        return itemDAO.searchByUPC(upc, storeName);
    }

    /**
     * This method searches items in a particular/given store using {@link ItemDAO} proxy.
     * @param make a string for item manufacturer
     * @param storeName a string for store name
     * @return list of item objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchByMake(String make, String storeName)
            throws KwickKioskDBException {

        return itemDAO.searchByMake(make, storeName);
    }

    /**
     * This method searches items in a given store using {@link ItemDAO} proxy.
     * @param model a string for item model
     * @param storeName a string for store name.
     * @return list of items
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> searchByModel(String model, String storeName)
            throws KwickKioskDBException {

        return itemDAO.searchByModel(model, storeName);
    }

    /**
     * This method retrieves items for a given store using {@link ItemDAO} proxy.
     * @param ctid an integer for category id as search criteria.
     * @param storeName a string for store name as search criteria.
     * @return a list of item objects.
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getItemsByCategory(int ctid, String storeName)
            throws KwickKioskDBException {
        return itemDAO.getItemsByCategory(ctid, storeName);
    }

    ///////////////////////////////////////////////////////////////////////
    // Shipping Method
    /**
     * This method retrieves available shipping methods for a province using {@link ShipDAO} proxy.
     * @param province  a string
     * @return list of shipping method objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<ShippingMethod> getExistShippingMethods(String province)
            throws KwickKioskDBException {
        return shipDAO.getShippingMethodList(province);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Store

    /**
     * This method adds a new store in database using {@link StoreDAO} proxy.
     * @param storeName string for name of store
     * @param phone string for phone number
     * @param taxCode string for tax code for the store
     * @param aptNo string for apartment number
     * @param stNo integer for street number
     * @param streetName string for name of street
     * @param postCode  string for postal code associated with location of store
     * @param city string for city where the store is located.
     * @param province a string for province
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean openNewStore(String storeName, String phone, String taxCode,
            String aptNo, int stNo, String streetName,
            String postCode, String city, String province)
            throws KwickKioskDBException {
        return storeDAO.addNewStore(storeName, phone, taxCode,
                aptNo, stNo, streetName,
                postCode, city, province);
    }

    /**
     * This method updates the store information in database using {@link StoreDAO} proxy.
     * @param originalStoreName string for earlier  name of store
     * @param store a store data transfer object
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean changeStoreInfo(String originalStoreName, Store store)
            throws KwickKioskDBException {
        return storeDAO.updateStore(originalStoreName, store);
    }

    /**
     * This method removes store information from database using {@link StoreDAO} proxy.
     * @param storeName a string for name of store.
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean closeDownStore(String storeName)
            throws KwickKioskDBException {
        return storeDAO.removeStore(storeName);
    }

    /**
     * This method retrieves all stores from database using {@link StoreDAO} proxy.
     * @return a list of store objects.
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Store> getAllStores() throws KwickKioskDBException {
        return storeDAO.getAllStores();
    }

    /**
     * This method adds an item into store using {@link ItemDAO} proxy.
     * @param storeName  a string for store name.
     * @param upc a string for item code
     * @param qty an integer for quantity of items
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean addItemToStore(String storeName, String upc, int qty)
            throws KwickKioskDBException {
        return itemDAO.addItemToStore(storeName, upc, qty);
    }

    /**
     * This method updates quantity of items in store using {@link ItemDAO} proxy.
     * @param storeName  a string for store name.
     * @param upc a string for item code
     * @param qty an integer for quantity of items
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean updateItemQTYInStore(String storeName, String upc, int qty)
            throws KwickKioskDBException {
        return itemDAO.updateItemQTYInStore(storeName, upc, qty);
    }
    /**
     * This method retrieves quantity of items in a store using {@link ItemDAO} proxy.
     * @param storeName a string for store name.
     * @param upc a string for item code
     * @return an integer indicating quantity of an item
     * @throws {@link KwickKioskDBException}
     */

    public int getItemQtyInStore(String storeName, String upc)
            throws KwickKioskDBException {
        return itemDAO.getItemQtyInStore(storeName, upc);
    }

    /**
     * This method retrieves all stores in a province using {@link StoreDAO} proxy.
     * @param province a string for province
     * @return list of stores
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Store> searchByProvince(String province)
            throws KwickKioskDBException {

        return storeDAO.searchByProvince(province);
    }

    /**
     * This method searches stores based on city as search criteria using {@link StoreDAO} proxy.
     * @param city  a string for city
     * @return list of store objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Store> searchByCity(String city)
            throws KwickKioskDBException {

        return storeDAO.searchByCity(city);
    }

   /**
    * This method searches stores based on name as search criteria using {@link StoreDAO} proxy.
    * @param name string for name of store
    * @return list of stores
    * @throws {@link KwickKioskDBException}
    */
    public ArrayList<Store> searchByName(String name)
            throws KwickKioskDBException {

        return storeDAO.searchByName(name);
    }

   /**
    * This method searches stores based on phone as search criteria using {@link StoreDAO} proxy.
    * @param phone a string
    * @return list of stores
    * @throws {@link KwickKioskDBException}
    */
    public ArrayList<Store> searchByPhone(String phone)
            throws KwickKioskDBException {

        return storeDAO.searchByPhone(phone);
    }

    /**
     * This method searches stores based on post code  as search criteria using {@link StoreDAO} proxy.
     * @param postCode a string
     * @return list of stores
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Store> searchByPostCode(String postCode)
            throws KwickKioskDBException {
        return storeDAO.searchByPostCode(postCode);
    }

    /**
     * This method retrieves tax rate associated with province  using {@link StoreDAO} proxy.
     * @param province a string for province
     * @return a double value for tax rate
     * @throws {@link KwickKioskDBException}
     */
    public double getTaxRate(String province)
            throws KwickKioskDBException {
        return storeDAO.getTaxRate(province);
    }

    ///////////////////////////////////////////////////////////////////////
    // Orders

    /**
     * This method inserts a new order into database  using {@link OrderDAO} proxy.
     * @param order  a data transfer object
     * @throws {@link KwickKioskDBException}
     */
    public int makeStoreOrder(Order order) throws KwickKioskDBException {
        int oid = orderDAO.insertStoreOrder(order);
        orderDAO.insertItems(order, oid);
        orderDAO.updateItemQtyInStore(order);
        paymentDAO.insertPayment(order, oid);
        return oid;
    }

    /**
     * This method inserts a new order made from web  using {@link OrderDAO} proxy.
     * @param order  a data transfer object
     * @return an integer for order id 
     * @throws {@link KwickKioskDBException}
     */
    public int makeDesktopOrder(Order order) throws KwickKioskDBException {
        int oid = orderDAO.insertDesktopOrder(order);
        orderDAO.insertItems(order, oid);
        orderDAO.updateItemQtyInStore(order);
        paymentDAO.insertPayment(order, oid);
        return oid;
    }

    /**
     * This method updates the status of an order using {@link OrderDAO} proxy.
     * @param id an integer for order id.
     * @param status a string for status of an order.
     * @return a boolean flag
     * @throws {@link KwickKioskDBException}
     */
    public boolean updateOrderStatus(int id, String status)
            throws KwickKioskDBException {
        return orderDAO.updateOrderStatus(id, status);
    }

    /**
     * This method searches orders by date using {@link OrderDAO} proxy.
     * @param date string for date as search criteria
     * @return a list of order objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Order> searchByDate(String date)
            throws KwickKioskDBException {
        return orderDAO.searchByDate(date);
    }

    /**
     * This method searches orders by order id  using {@link OrderDAO} proxy.
     * @param i an integer for order id
     * @return an order object
     * @throws {@link KwickKioskDBException}
     */
    public Order searchByOrderNum(int i)
            throws KwickKioskDBException {
        return orderDAO.searchByNum(i);
    }

    /**
     * This method searches orders by order status using {@link OrderDAO} proxy.
     * @param status a string for status of an order
     * @return  a list of order objects
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Order> searchByStatus(String status)
            throws KwickKioskDBException {
        return orderDAO.searchByStatus(status);
    }

    /**
     * This method retrieves all orders from database using {@link OrderDAO} proxy.
     * @return a list of orders
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Order> getAllOrder()
            throws KwickKioskDBException {
        return orderDAO.getAllOrder();
    }

    /**
     * This method retrieves orders placed by a customer using {@link OrderDAO} proxy.
     * @param csid an integer for customer id
     * @return a list of orders 
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Order> getCustomerOrder(int csid)
            throws KwickKioskDBException {
        return orderDAO.getCustomerOrder(csid);
    }

    /**
     * This method retrieves item information associated with an order using {@link OrderDAO} proxy.
     * @param oid an integer for order id.
     * @return a list of items.
     * @throws {@link KwickKioskDBException}
     */
    public ArrayList<Item> getItemByOrder(int oid)
            throws KwickKioskDBException {
        return orderDAO.getItemByOrder(oid);
    }

    ///////////////////////////////////////////////////////
    // Admin report stuff
    /**
     * This method retrieves a report data  using {@link AdminDAO} proxy.
     * @param postCodeList a list of postal codes  as criteria
     * @param startDate a string for start date as criteria
     * @param endDate a string for end date as criteria
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getAreaReport(List<String> postCodeList,
            String startDate, String endDate)
            throws KwickKioskDBException {

        Vector<Vector> report = new Vector<Vector>();
        for (int i = 0; i != postCodeList.size(); i++) {
            report.add(adminDAO.getAreaStat(postCodeList.get(i),
                    startDate, endDate));
        }
        return report;
    }

    /**
     * This method retrieves a report data  using {@link AdminDAO} proxy.
     * @param storeList a list of stores
     * @param startDate  a string for start date as criteria
     * @param endDate a string for end date as criteria
     * @return  a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getStoreReport(List<String> storeList,
            String startDate, String endDate)
            throws KwickKioskDBException {

        Vector<Vector> report = new Vector<Vector>();
        for (int i = 0; i != storeList.size(); i++) {
            report.add(adminDAO.getStoreStat(storeList.get(i),
                    startDate, endDate));
        }
        return report;
    }

    /**
     * This method retrieves a report data  using {@link AdminDAO} proxy.
     * @param upcList a list of item codes
     * @param startDate a string for start date as criteria
     * @param endDate a string for end date as criteria
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getItemReport(List<String> upcList,
            String startDate, String endDate)
            throws KwickKioskDBException {

        Vector<Vector> report = new Vector<Vector>();
        for (int i = 0; i != upcList.size(); i++) {
            report.add(adminDAO.getItemStat(upcList.get(i),
                    startDate, endDate));
        }
        return report;
    }

    /**
     * This method retrieves report data for inventory using {@link AdminDAO} proxy.
     * @param storeName a string for store name
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getInventoryReport(String storeName)
            throws KwickKioskDBException {

        return adminDAO.getInventoryReport(storeName);
    }

    /**
     * This method retrieves postal codes for stores using {@link AdminDAO} proxy.
     * @return  a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getPostCode() throws KwickKioskDBException {
        return adminDAO.getPostCode();
    }

    /**
     * This method retrieves all postal codes for a city using {@link AdminDAO} proxy.
     * @param city a string
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getPostCodeByCity(String city)
            throws KwickKioskDBException {

        return adminDAO.getPostCodeByCity(city);
    }

    /**
     * This method retrieves all postal codes for a province using {@link AdminDAO} proxy.
     * @param province a string
     * @return a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> getPostCodeByProvince(String province)
            throws KwickKioskDBException {

        return adminDAO.getPostCodeByProvince(province);
    }

    /**
     * This method searches a store based on postal code using {@link AdminDAO} proxy.
     * @param code a string for postal code
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector> searchPostCode(String code)
            throws KwickKioskDBException {

        return adminDAO.searchPostCode(code);
    }

    /**
     * This method retrieves data required to view chart for items using {@link AdminDAO} proxy.
     * @param upc a string for item code.
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getItemChartStat(String upc,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getItemChartStat(upc, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for items using {@link AdminDAO} proxy.
     * @param upc a string for item code.
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getItemChartMthStat(String upc,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getItemChartMthStat(upc, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for items using {@link AdminDAO} proxy.
     * @param upc a string for item code.
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getItemChartYearStat(String upc,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getItemChartYearStat(upc, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store using {@link AdminDAO} proxy.
     * @param store string for name of store
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result 
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getStoreChartStat(String store,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getStoreChartStat(store, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store using {@link AdminDAO} proxy.
     * @param store string for name of store
     * @param startDate  a string for start date
     * @param endDate a string
     * @return a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getStoreChartMthStat(String store,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getStoreChartMthStat(store, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store using {@link AdminDAO} proxy.
     * @param store string for name of store
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getStoreChartYearStat(String store,
            String startDate,
            String endDate)
            throws KwickKioskDBException {

        return adminDAO.getStoreChartYearStat(store, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store based on area using {@link AdminDAO} proxy.
     * @param postCode a string for postal code
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getAreaChartStat(String postCode,
                                                 String startDate,
                                                 String endDate)
    throws KwickKioskDBException {

        return adminDAO.getAreaChartStat(postCode, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store based on area using {@link AdminDAO} proxy.
     * @param postCode a string for postal code
     * @param startDate a string for start date
     * @param endDate a string
     * @return a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getAreaChartMthStat(String postCode,
                                                 String startDate,
                                                 String endDate)
    throws KwickKioskDBException {

        return adminDAO.getAreaChartMthStat(postCode, startDate, endDate);
    }

    /**
     * This method retrieves data required to view chart for store based on area using {@link AdminDAO} proxy.
     * @param postCode a string for postal code
     * @param startDate a string for start date
     * @param endDate a string
     * @returnc a vectored object as result
     * @throws {@link KwickKioskDBException}
     */
    public Vector<Vector<String>> getAreaChartYearStat(String postCode,
                                                 String startDate,
                                                 String endDate)
    throws KwickKioskDBException {

        return adminDAO.getAreaChartYearStat(postCode, startDate, endDate);
    }
}
